<template>
<div class="blood-chart" v-loading="loading">
    <el-tooltip v-if="fullScreenBtn" content="全屏" placement="top">
        <i class="iconfont icon-quanping full-screen" :class="{'full-screen-active': fullScreen}" @click="handleFullSreen"></i>
    </el-tooltip>
    <div id="relyTask" :style="isAll ? 'height:80%' : 'height:100%'"></div>
    <div v-show="isAll" style="height:20%">
        <div class="no-rely-title" style="line-height:24px;">未依赖任务</div>
        <div id="noRelyTask" style="height:calc(100% - 24px)"></div>
    </div>
</div>
</template>

<script>
export default {
    name: 'BloodChart',
    props: {
        isAll: {
            type: Boolean,
            default: () => { return false }
        },
        fullScreenBtn: {
            type: Boolean,
            default: () => {
                return false
            }
        },
        fullScreen: {
            type: Boolean,
            default: () => { return false }
        },
        data: {
            type: Array,
            default: () => { return [] }
        }
    },
    data () {
        return {
            loading: false,
            relyTask: [],
            noRelyTask: []
        }
    },
    mounted () {
        this.init()
    },
    methods: {
        setLevel (id) {
            let arr = this[id]
            if (id === 'noRelyTask') {
                for (let i = 0; i < arr.length; i++) {
                    arr[i].level = 1
                }
            }
            if (id === 'relyTask') {
                const fn = (n, sub) => {
                    for (let i = 0; i < sub.length; i++) {
                        sub[i].level = n
                        if (sub[i].upstreamSchedules && sub[i].upstreamSchedules.length) {
                            fn(n--, sub[i].upstreamSchedules)
                        }
                    }
                }
                fn(99999, arr)
                let num = arr.map(v => v.level)
                let min = Math.min(...num)
                for (let i = 0; i < arr.length; i++) {
                    arr[i].level = arr[i].level - min + 1
                }
            }
            return arr
        },
        getXY (arr, id) {
            if (id === 'relyTask') {
                let levels = []
                let obj = {}
                for (let i = 0; i < arr.length; i++) {
                    if (!obj[arr[i].level]) {
                        obj[arr[i].level] = 1
                        levels.push(arr[i].level)
                    } else {
                        obj[arr[i].level]++
                    }
                }
                return {
                    yNum: levels.length,
                    xNum: Math.max(...Object.values(obj))
                }
            } else {
                return {
                    yNum: 1,
                    xNum: arr.length
                }
            }
        },
        init () {
            this.loading = true
            if (this.isAll) {
                this.data.forEach(item => {
                    let up = item.upstreamSchedules && item.upstreamSchedules.length
                    let down = item.downstreamSchedules && item.downstreamSchedules.length
                    if (!up && !down) {
                        this.noRelyTask.push(item)
                    } else {
                        this.relyTask.push(item)
                    }
                })
                this.setChart('relyTask')
                this.setChart('noRelyTask')
            } else {
                this.relyTask = this.data
                this.setChart('relyTask')
            }
            this.loading = false
        },
        setChart (id) {
            let data = this.setLevel(id)
            let { yNum, xNum } = this.getXY(data, id)
            let img = require('../../../assets/img/WhxKECPNujWoWEFNdnJE.png')
            let dom = document.getElementById(id)
            let bloodChart = this.$echarts.init(dom)
            let symbolSize = 50 // 节点大小
            let maxWidth = dom.clientWidth // 容器宽度
            let maxHeight = dom.clientHeight // 容器高度
            let xBase = parseInt((maxWidth / xNum / 2) - (symbolSize / 2)) // 初始点横轴的位置
            let xGap = parseInt(maxWidth / xNum) // 节点横轴间距
            let yBase = parseInt((maxHeight / yNum / 2) - (symbolSize / 2)) // 初始点纵轴的位置
            let yGap = parseInt(maxHeight / yNum) // 节点纵轴间距
            let links = [] // 连线列表
            let nodes = [] // 节点列表
            let obj = {}
            for (let i = 0; i < data.length; i++) {
                const { scheduleName, downstreamSchedules, level } = data[i]
                !obj[level] ? obj[level] = 1 : obj[level]++
                nodes.push({
                    name: scheduleName,
                    x: xGap * (obj[level] - 1) + xBase,
                    y: yGap * (level - 1) + yBase
                })
                for (let n = 0; n < downstreamSchedules.length; n++) {
                    links.push({
                        source: scheduleName,
                        target: downstreamSchedules[n].scheduleName
                    })
                }
            }
            let option = {
                tooltip: {
                    trigger: 'item',
                    formatter: '{b}'
                },
                series: [
                    {
                        type: 'graph',
                        layout: 'none',
                        roam: true,
                        draggable: false,
                        label: {
                            normal: {
                                show: false,
                                textStyle: {
                                    color: '#2680EB'
                                },
                                position: 'bottom'
                            }
                        },
                        animation: false,
                        symbol: `image://${img}`,
                        symbolSize,
                        edgeSymbol: ['circle', 'arrow'],
                        edgeSymbolSize: [0, 6],
                        edgeLabel: {
                            normal: {
                                textStyle: {
                                    fontSize: 20
                                }
                            }
                        },
                        // itemStyle: {
                        //     normal: {
                        //         show: true,
                        //         borderColor: '#2680EB',
                        //         color: '#fff'
                        //     }
                        // },
                        data: nodes,
                        links,
                        lineStyle: {
                            normal: {
                                opacity: 1,
                                width: 1,
                                curveness: 0
                            }
                        }
                    }
                ]
            }
            bloodChart.setOption(option, true)
            window.addEventListener('resize', () => bloodChart.resize())
            bloodChart.on('click', param => {
                if (param.dataType === 'node') {
                    console.warn('点击了节点', param.name)
                    this.$emit('item', this.data.filter(v => v.scheduleName === param.name)[0])
                } else {
                    console.warn('点击了连线', param.name)
                }
            })
        },
        handleFullSreen () {
            this.$emit('fullScreen', !this.fullScreen)
        }
    }
}
</script>

<style lang="less">
.blood-chart {
    width: 100%;
    height: 100%;
    overflow: hidden;
    position: relative;

    .full-screen {
        position: absolute;
        cursor: pointer;
        right: 20px;
        top: 10px;
        z-index: 1;
    }

    .full-screen-active {
        color: #409eff;
    }
    .no-rely-title {
        font-size: 18px;
        border-top: 1px solid #DCDFE6;
    }
}
</style>
